package com.anti.modular.sys.dict.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil;
import com.anti.commom.constant.CommonConstant;
import com.anti.commom.core.exception.BusinessException;
import com.anti.commom.core.exception.enums.StatusExceptionEnum;
import com.anti.commom.enums.CommonStatusEnum;
import com.anti.core.context.login.LoginContextHolder;
import com.anti.jdbc.DBUtils;
import com.anti.jdbc.support.page.PageParam;
import com.anti.jdbc.support.page.PageResult;
import com.anti.modular.sys.dict.entity.SysDictData;
import com.anti.modular.sys.dict.enums.SysDictDataExceptionEnum;
import com.anti.modular.sys.dict.param.SysDictDataParam;
import com.anti.modular.sys.dict.service.SysDictDataService;
import org.omg.Messaging.SYNC_WITH_TRANSPORT;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Description TODO
 * @Author anTi
 * @Date 2021-3-5
 */
@Service
public class SysDictDataServiceImpl implements SysDictDataService {
    @Resource
    DBUtils dbUtils;


    @Override
    public PageResult page(PageParam pageParam, SysDictDataParam sysDictDataParam) {
        //构造条件
        StringBuilder sb=new StringBuilder("select * from sys_dict_data where status<>2 ");
        ArrayList<Object> params = CollectionUtil.newArrayList();
        if (ObjectUtil.isNotNull(sysDictDataParam)) {
            //根据字典类型查询
            if (ObjectUtil.isNotEmpty(sysDictDataParam.getTypeId())) {
                sb.append(" and type_id = ? ");
                params.add(sysDictDataParam.getTypeId());
            }
            //根据字典值的编码模糊查询
            if (ObjectUtil.isNotEmpty(sysDictDataParam.getCode())) {
                sb.append(" and code like ? ");
                params.add("%"+sysDictDataParam.getCode()+"%");
            }
            //根据字典值的内容模糊查询
            if (ObjectUtil.isNotEmpty(sysDictDataParam.getValue())) {
                sb.append(" and value like ? ");
                params.add("%"+sysDictDataParam.getValue()+"%");
            }
        }
        //根据排序升序排列，序号越小越在前
        sb.append(" order by sort asc");
        //返回分页查询结果
        PageResult pageResult = dbUtils.query(pageParam, sb.toString(), params.toArray());
        return pageResult;
    }

    @Override
    public List<SysDictData> list(SysDictDataParam sysDictDataParam) {
        //构造条件,查询某个字典类型下的
        StringBuilder sb = new StringBuilder("select * from sys_dict_data where status <> 2 ");
        ArrayList<Object> param = CollectionUtil.newArrayList();
        if (ObjectUtil.isNotNull(sysDictDataParam)) {
            if (ObjectUtil.isNotEmpty(sysDictDataParam.getTypeId())) {
                sb.append(" and type_id =? ");
                param.add(sysDictDataParam.getTypeId());
            }
        }
        //根据排序升序排列，序号越小越在前
        sb.append(" order by sort asc ");
        return dbUtils.query(sb.toString(), SysDictData.class, param.toArray());
    }

    @Override
    public void add(SysDictDataParam sysDictDataParam) {

        //校验参数，检查是否存在重复的编码，不排除当前添加的这条记录
        checkParam(sysDictDataParam, false);

        //将dto转为实体
        SysDictData sysDictData = new SysDictData();
        BeanUtil.copyProperties(sysDictDataParam, sysDictData);
        sysDictData.setCreateTime(new Date());
        sysDictData.setCreateUser(LoginContextHolder.me().getSysLoginUserId());
        //设置状态为启用
        sysDictData.setStatus(CommonStatusEnum.ENABLE.getCode());

        dbUtils.insert(sysDictData);
    }

    @Override
    public void delete(SysDictDataParam sysDictDataParam) {
        //根据id查询实体
        SysDictData sysDictData = this.querySysDictData(sysDictDataParam);

        //逻辑删除，修改状态
        sysDictData.setStatus(CommonStatusEnum.DELETED.getCode());

        //更新实体
        dbUtils.update(sysDictData);
    }

    @Override
    public void edit(SysDictDataParam sysDictDataParam) {

        //根据id查询实体
        SysDictData sysDictData = this.querySysDictData(sysDictDataParam);

        //校验参数，检查是否存在重复的编码或者名称，排除当前编辑的这条记录
        checkParam(sysDictDataParam, true);

        //请求参数转化为实体
        BeanUtil.copyProperties(sysDictDataParam, sysDictData);

        //不能修改状态，用修改状态接口修改状态
        sysDictData.setStatus(null);
        sysDictData.setUpdateTime(new Date());
        sysDictData.setUpdateUser(LoginContextHolder.me().getSysLoginUserId());
        dbUtils.update(sysDictData);
    }

    @Override
    public SysDictData detail(SysDictDataParam sysDictDataParam) {
        return this.querySysDictData(sysDictDataParam);
    }

    @Override
    public void deleteByTypeId(Long dictTypeId) {
        String sql="update sys_dict_data set status=2 where type_id =? ";
        dbUtils.execSql(sql,dictTypeId);
    }

    @Override
    public void updateChangeStatus(SysDictDataParam sysDictDataParam) {
        //根据id查询实体
        SysDictData sysDictData = this.querySysDictData(sysDictDataParam);
        Long id = sysDictData.getId();

        Integer status = sysDictDataParam.getStatus();

        //校验状态在不在枚举值里
        CommonStatusEnum.validateStatus(status);

        //更新枚举，更新只能更新未删除状态的
        String sql="update sys_dict_data set status=? where id =? and status <> 2";
        int i = dbUtils.execSql(sql, status, id);
        if (i<=0) {
            throw new BusinessException(StatusExceptionEnum.UPDATE_STATUS_ERROR);
        }
    }

    @Override
    public List<Dict> getDictDataListByDictTypeId(Long dictTypeId) {
        //构造查询条件
        String sql="select * from sys_dict_data where type_id=? and status=0 order by sort asc";
        List<SysDictData> results = dbUtils.query(sql,SysDictData.class,dictTypeId);

        //抽取code和value封装到map返回
        List<Dict> dictList = CollectionUtil.newArrayList();
        results.forEach(sysDictData -> {
            Dict dict = Dict.create();
            dict.put(CommonConstant.CODE, sysDictData.getCode());
            dict.put(CommonConstant.VALUE, sysDictData.getValue());
            dictList.add(dict);
        });
        return dictList;
    }

    @Override
    public SysDictData getDicDataByTypeNameAndDataValue(String dictType, String dictDataValue) {
        String sql="select * from sys_dict_data where type_id=(select id from sys_dict_type where code=?) and code=? ";
        SysDictData dictData = dbUtils.getFirst(sql, SysDictData.class, dictType, dictDataValue);
        if (ObjectUtil.isNull(dictData)) {
            throw new BusinessException(SysDictDataExceptionEnum.DICT_DATA_NOT_EXIST);
        }
        return dictData;
    }

    /**
     * 校验参数，校验是否存在相同的编码
     */
    private void checkParam(SysDictDataParam sysDictDataParam, boolean b) {
        Long id = sysDictDataParam.getId();
        Long typeId = sysDictDataParam.getTypeId();
        String code = sysDictDataParam.getCode();

        //构建带code的查询条件
        StringBuilder sb=new StringBuilder("select count(*) from sys_dict_data where status <> 2 and type_id =? and code =? ");
        ArrayList<Object> params = CollectionUtil.newArrayList();
        params.add(typeId);
        params.add(code);

        //如果排除自己，则增加查询条件主键id不等于本条id
        if (b) {
            sb.append(" and id <> ?");
            params.add(id);
        }

        //查询重复记录的数量
        int countByCode = dbUtils.getIntValue(sb.toString(),params.toArray());

        //如果存在重复的记录，抛出异常，直接返回前端
        if (countByCode >= 1) {
            throw new BusinessException(SysDictDataExceptionEnum.DICT_DATA_CODE_REPEAT);
        }
    }

    /**
     * 获取系统字典值
     */
    private SysDictData querySysDictData(SysDictDataParam sysDictDataParam) {
        SysDictData sysDictData = dbUtils.get("select * from sys_dict_data where id =?",SysDictData.class,sysDictDataParam.getId());
        if (ObjectUtil.isNull(sysDictData)) {
            throw new BusinessException(SysDictDataExceptionEnum.DICT_DATA_NOT_EXIST);
        }
        return sysDictData;
    }
}
